package reservation.v2;

import java.io.IOException;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

/**
 * Classe serveur : représente le coeur de l'application. Elle effectue toutes les opérations relatives à 
 * la demande du client. C'est la seule classe qui est en relation avec les fichiers de données
 * 
 * @author Alexandre Boursier and Jérome Boursier
 * @version 2011.11.20
 */

public class Serveur {

    /**
     * Statut définissant l'activité du serveur
     */
    private static boolean status;

    /**
     * Constructeur par défaut
     */
    public Serveur() {}

    /**
     * @return le statut courant du serveur
     */
    public static boolean isStatus() {
        return status;
    }

    /**
     * Init : la création du serveur entraine la création du fichier
     * @throws IOException  
     */
    public void init() throws IOException
    {
        SerializeText.creerFichier();
        System.out.println("Serveur créé");
    }

    /**
     * Ouvrir le serveur en chargeant les données actuelles de ce dernier
     * 
     * @throws NumberFormatException
     * @throws NullPointerException
     * @throws NegativeValueException
     * @throws StartStopException
     * @throws IOException
     * @throws ParseException
     */
    public void open() throws NumberFormatException, NullPointerException, 
    NegativeValueException, StartStopException, IOException, ParseException 
    {
        status = true;
        SerializeText.load();
        System.out.println("Serveur ouvert -- Fichiers de données chargés");
    }

    /**
     * Fermer le serveur courant
     */
    public void close()
    {
        status = false;
        SerializeText.close();
        System.out.println("Le serveur est actuellement fermé");
    }

    /**
     * Traiter la demande de réservation d'un client simple et lui indiquer la réponse
     * @param c
     *          Le client demandeur
     * @param t
     *          Le trajet cible
     * @return
     * @throws IOException
     */
    public static boolean traiterDemandeReservation(Client c, Trajet t) throws IOException
    {
        if(isStatus())
        {
            if (SerializeText.store(c, t))
            {
                System.out.println("Votre réservation est confirmée");
                return true;
            }
            else
            {
                System.out.println("Votre demande de réservation n'a pas pu aboutir");
                return false;
            }
        }
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
            return false;
        }
    }

    /**
     * Ajouter un transport
     * @param t
     *          Le transport cible
     * @return true si le transport est ajouté à la base de données, false sinon
     * @throws NumberFormatException
     * @throws NullPointerException
     * @throws IOException
     * @throws NegativeValueException
     * @throws StartStopException
     */
    public boolean add(Transport t) throws NumberFormatException, NullPointerException, 
    IOException, NegativeValueException, StartStopException
    {
        if(isStatus())
        {
            if (SerializeText.store(t))
            {
                System.out.println("Transport ajouté avec succès.");
                System.out.println(t);
                return true;
            }
            else
            {
                System.out.println("Erreur lors de l'ajout, la demande n'a pue aboutir");
                return false;
            }
        }
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
            return false;
        }
    }

    /**
     * Ajouter un trajet
     * @param t
     *          Le trajet cible
     * @return true si le transport est ajouté à la base de données, false sinon
     * @throws NumberFormatException
     * @throws NullPointerException
     * @throws IOException
     * @throws NegativeValueException
     * @throws StartStopException
     */
    public boolean add(Trajet t) throws NumberFormatException, NullPointerException, 
    IOException, NegativeValueException, StartStopException
    {
        if(isStatus())
        {
            if (SerializeText.store(t))
            {
                System.out.println("Trajet ajouté avec succès.");
                System.out.println(t);
                return true;
            }
            else
            {
                System.out.println("Erreur lors de l'ajout, la demande n'a pue aboutir");
                return false;
            }
        }
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
            return false;
        }
    }

    /**
     * Supprimer un transport
     * @param t
     *          Le transport cible
     * @return true si le transport est modifié, false sinon
     * @throws NumberFormatException
     * @throws NullPointerException
     * @throws IOException
     * @throws NegativeValueException
     * @throws StartStopException
     */
    public boolean delete(Transport t) throws NumberFormatException, NullPointerException, 
    IOException, NegativeValueException, StartStopException
    {
        if(isStatus())
        {
            if (SerializeText.delete(t))
            {
                System.out.println("Transport supprimé avec succès.");
                return true;
            }
            else
            {
                System.out.println("Erreur lors de la suppression, la demande n'a pue aboutir");
                return false;
            }
        }
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
            return false;
        }

    }

    /**
     * Supprimer un trajet
     * @param t
     *          Le trajet cible
     * @return true si le trajet est modifié, false sinon
     * @throws NumberFormatException
     * @throws NullPointerException
     * @throws IOException
     * @throws NegativeValueException
     * @throws StartStopException
     */
    public boolean delete(Trajet t) throws NumberFormatException, NullPointerException, 
    IOException, NegativeValueException, StartStopException
    {
        if(isStatus())
        {
            if (SerializeText.delete(t))
            {
                System.out.println("Trajet supprimé avec succès.");
                return true;
            }
            else
            {
                System.out.println("Erreur lors de la suppression, la demande n'a pue aboutir");
                return false;
            }
        }
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
            return false;
        }
    }

    /**
     * Modifier un transport
     * @param t
     *          Le transport cible
     * @return true si le transport est modifié, false sinon
     * @throws NumberFormatException
     * @throws NullPointerException
     * @throws IOException
     * @throws NegativeValueException
     * @throws StartStopException
     */
    public boolean alter(Transport t) throws NumberFormatException, NullPointerException, 
    IOException, NegativeValueException, StartStopException
    {
        if(isStatus())
        {
            if (SerializeText.alter(t))
            {
                System.out.println("Transport modifié avec succès.");
                System.out.println(t);
                return true;
            }
            else
            {
                System.out.println("Erreur lors de la modification, la demande n'a pue aboutir");
                return false;
            }
        }
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
            return false;
        }
    }

    /**
     * Modifier un trajet
     * @param t
     *          Le trajet cible
     * @return true si le trajet est modifié, false sinon
     * @throws NumberFormatException
     * @throws NullPointerException
     * @throws IOException
     * @throws NegativeValueException
     * @throws StartStopException
     */
    public boolean alter(Trajet t) throws NumberFormatException, NullPointerException, 
    IOException, NegativeValueException, StartStopException
    {
        if(isStatus())
        {
            if (SerializeText.alter(t))
            {
                System.out.println("Trajet modifié avec succès.");
                System.out.println(t);
                return true;
            }
            else
            {
                System.out.println("Erreur lors de la modification, la demande n'a pue aboutir");
                return false;
            }
        }
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
            return false;
        }
    }

    /**
     * Liste des trajets
     */
    public String afficherTrajets(List<Trajet> trajets) {
        if(isStatus())
        {
            StringBuilder sb = new StringBuilder();
            for (Trajet t : trajets) {
                sb.append(t.toString());
            }
            return sb.toString();
        }
        else 
        {
            return "Aucune connexion avec le serveur";
        }
    }

    /**
     * Liste des transports
     */
    public String afficherTransports(List<Transport> transports) {
        if(isStatus())
        {
            StringBuilder sb = new StringBuilder();
            for (Transport t : transports) {
                sb.append(t.toString());
            }
            return sb.toString();
        }
        else 
        {
            return "Aucune connexion avec le serveur";
        }
    }


    /**
     * Liste des trajets
     */
    public void listeTrajets() {
        if(isStatus())
        {
            System.out.println(SerializeText.listeTrajets());
        }
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
        }
    }


    /**
     * Liste des transports
     */
    public void listeTransports() {
        if(isStatus())
        {
            System.out.println(SerializeText.listeTransports());
        }
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
        }
    }

    /**
     * Obtenir un transport en fonction de son identifiant
     * 
     * @param id
     *          L'identifiant du transport cible
     * @return
     */
    public Transport obtenirTransport(int id)
    {
        Transport t = null;
        if(isStatus())
        {
            return SerializeText.getTransportById(id);
        }
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
            return t;
        }     
    }

    /**
     * Obtenir un trajet en fonction de son identifiant
     * 
     * @param id
     *          L'identifiant du trajet cible
     * @return
     */
    public Trajet obtenirTrajet(int id)
    {
        Trajet t = null;
        if(isStatus())
        {
            return SerializeText.getTrajetById(id);
        }
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
            return t;
        }
    }

    /**
     * Obtenir les trajets dont le client cible fait partie
     * @param c
     *          Le client cible
     */
    public void obtenirTrajets(Client c)
    {
        if(isStatus())
        {
            System.out.println(afficherTrajets(SerializeText.getTrajetsByClient(c)));
        } 
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
        }
    }

    /**
     * Obtenir les trajets dont le transport cible fait partie
     * @param t
     *          Le transport cible
     */
    public void obtenirTrajets(Transport t)
    {
        if(isStatus())
        {
            System.out.println(afficherTrajets(SerializeText.getTrajetsByTransport(t)));
        } 
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
        }
    }

    /**
     * Obtenir les trajets pour une date donnée
     * @param d
     *          La date cible
     */
    public void obtenirTrajets(Date d)
    {
        if(isStatus())
        {
            System.out.println(afficherTrajets(SerializeText.getTrajetsByDate(d)));
        } 
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
        }
    }

    /**
     * Obtenir les trajets pour une ville de départ donnée
     * @param v
     *          La ville cible
     */
    public void obtenirTrajets(Ville v)
    {
        if(isStatus())
        {
            System.out.println(afficherTrajets(SerializeText.getTrajetsByVille(v)));
        } 
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
        }
    } 

    /**
     * Obtenir les transports partant à une date donnée 
     * @param d 
     *          La date cible
     */
    public void obtenirTransports(Date d)
    {
        if(isStatus())
        {
            System.out.println(afficherTransports(SerializeText.getTransportsByDate(d)));
        } 
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
        }
    }

    /**
     * Obtenir les transports partant à une date donnée 
     * @param V
     *          La ville cible
     */
    public void obtenirTransports(Ville v)
    {
        if(isStatus())
        {
            System.out.println(afficherTransports(SerializeText.getTransportsByVille(v)));
        } 
        else 
        {
            System.out.println("Aucune connexion avec le serveur");
        }
    }

    /**
     * Convertir en date
     * 
     * @param s
     *          La chaîne de caractères cible
     * @throws ParseException
     */
    public Date toDate(String s) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
        return sdf.parse(s);
    }

}
